home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 2 / Amiga Tools 2.iso / tools / jade / lisp / xc.jl < prev    next >
Text File  |  1995-03-09  |  5KB  |  146 lines

  1. ;;;; xc-mode.jl -- new indentation for C mode
  2.  
  3. ;;; Needless to s0¼Ö6ǟ&ñX9ÃÔòèÆ¡NPúüe!Mž YGDL%1-€åe³t@—8)ñ5ÕF"DÉ©ínð:Z×ÔÃÀL»(9BJæËü€JŽ)Æl¢%яʔúR³xŠPPË}j\lJúNˆ/VÎ6Ú4ÃÑ„Üao,2Dè»×Dà!!¾¶6Y f6–7œ×ÂlؼrS̨Ž©È sfŽ|ùؕéåØJÚyæñðúñ•Âí¼ðffÆ
  4. 4µ2X^umIÁ…`¤ÊŠœyç¤x|‰Ñ ål¦Ï¥N¼@%ß<Ì­‘æm¥D3
  5. ž EŽXåêêLEu™8*µžO\o¦V1¬¥r“HZ
  6. ùP %›À@Ñ DáºÕ^S×ML
  7. ^’ wÕŒ*Å~S·<àYñ<à   -2   -5
  8.  
  9. (defvar c-body-indent 4
  10.   "Indentation of code with respect to its containing block.")
  11. (defvar c-brace-indent -4
  12.   "Extra indentation of braces relative to the body of the code they
  13. contain.")
  14. (defvar c-case-indent -4
  15.   "Extra indentation for case statements.")
  16. (defvar c-label-indent -4
  17.   "Extra indentation for labels.")
  18.  
  19.  
  20. ;; Installation; hooks into c-mode, installing its own indentation function
  21. (add-hook 'c-mode-hook #'(lambda ()
  22.                (setq mode-indent-line 'xc-indent-line
  23.                  mode-name "XC")
  24.                (eval-hook 'xc-mode-hook)
  25.                nil))
  26.  
  27.  
  28. ;; The business
  29.  
  30. (defun xc-indent-line (&optional pos)
  31.   "Indent the line at POS (or the cursor) assuming that it's C source code."
  32.   (set-indent-pos (xc-indent-pos pos)))
  33.  
  34. ;; Attempt to find the previous statement
  35. (defun xc-backward-stmt (pos)
  36.   (let*
  37.       (stmt-pos
  38.        back-1-pos)
  39.     (error-protect
  40.     (while (setq pos (c-backward-exp 1 pos t))
  41.       (cond
  42.        ((null back-1-pos)
  43.         (setq back-1-pos pos))
  44.        ((/= (pos-line back-1-pos) (pos-line pos))
  45.         ;; Gone past the start of this line
  46.         (error "Ignored")))        ; break the loop
  47.       (setq stmt-pos pos))
  48.       (error))
  49.     stmt-pos))
  50.  
  51. ;; POS should point to an `else' keyword, the position of it's matching `if'
  52. ;; will be returned.
  53. (defun xc-balance-ifs (pos &optional depth)
  54.   (unless depth
  55.     (setq depth 1))
  56.   (while (and (/= depth 0)
  57.           (setq pos (xc-backward-stmt pos)))
  58.     (cond
  59.      ((and (looking-at "else[\t ]*" pos)
  60.        (not (looking-at "[\t ]*if[\t ]*\\(" (match-end))))
  61.       (setq depth (1+ depth)))
  62.      ((looking-at "if" pos)
  63.       (setq depth (1- depth)))))
  64.   (when (zerop depth)
  65.     pos))
  66.  
  67. ;; Work out where to indent LINE-POS to.
  68. (defun xc-indent-pos (&optional line-pos)
  69.   (setq line-pos (if line-pos
  70.              (line-start line-pos)
  71.            (line-start)))
  72.   ;; Check for cpp op
  73.   (if (regexp-match-line "^[\t ]*#" line-pos)
  74.       (pos 0 (pos-line line-pos))
  75.     (let*
  76.     ((pos (copy-pos line-pos))
  77.      (exp-pos (xc-backward-stmt pos))
  78.      exp-ind)
  79.       ;; Find the beginning of the expression to indent relative to
  80.       (unless exp-pos
  81.     ;; Start of the containing expression
  82.     (when (find-prev-regexp "[\{\(]" pos)
  83.       (setq exp-pos (match-start))))
  84.       (setq exp-ind (char-to-glyph-pos exp-pos))
  85.       (unless (equal (indent-pos exp-pos) exp-ind)
  86.     (when (and (regexp-match-line "^[\t ]*([^][(){}\"'a-zA-Z0-9_\t ]+)"
  87.                       (line-start exp-pos))
  88.            (< (match-start 1) exp-pos))
  89.       ;; Back up over the bits of punctuation
  90.       (setq exp-ind (char-to-glyph-pos (match-start 1)))))
  91.       ;; First look at previous line and see how it affects the one we're
  92.       ;; trying to indent
  93.       (cond
  94.        ((= (get-char exp-pos) ?\})
  95.     (unless (zerop (pos-col exp-pos))
  96.       (left-char (+ c-body-indent c-brace-indent) exp-ind)))
  97. ;      ((regexp-match-line "^[\t ]*{" exp-pos)
  98. ;    (setq exp-ind (right-char c-body-indent (indent-pos exp-pos))))
  99.        ((looking-at ".*{" exp-pos)
  100.     (setq exp-ind (right-char c-body-indent (indent-pos exp-pos))))
  101.        ((looking-at "(if|for|while|switch)[\t ]*\\(.*$|(else|do)([^a-z]|$)"
  102.             exp-pos)
  103.     (right-char c-body-indent exp-ind))
  104.        ((= (get-char exp-pos) ?\}))
  105.        ((looking-at ".*\;" exp-pos)
  106.     (let
  107.         ((prev (xc-backward-stmt exp-pos)))
  108.       ;; *Need to loop here searching back to the correct level*
  109.       (when (and prev (/= (pos-col prev) (pos-col exp-pos))
  110.              (not (looking-at "case .*:|default[\t ]*:|.*;" prev)))
  111.         ;; A continuation?
  112.         (when (and (looking-at "else[\t ]*" prev)
  113.                (not (looking-at "[\t ]*if[\t ]*\\(" (match-end))))
  114.           (unless (setq prev (xc-balance-ifs prev))
  115.         (error "Beginning of buffer"))
  116.           (let
  117.           ((tmp (xc-backward-stmt prev)))
  118.         (while (and tmp (looking-at "if[\t ]*\\(" tmp))
  119.           (setq prev tmp)
  120.           (unless (setq tmp (xc-backward-stmt tmp))
  121.             (error "Beginning of buffer")))))
  122.         (set-pos-col exp-ind (pos-col (char-to-glyph-pos prev))))))
  123.        ((looking-at "case .*:|default[\t ]*:" exp-pos)
  124.     (left-char c-case-indent exp-ind))
  125.        ((looking-at "[a-zA-Z_][a-zA-Z0-9_]+:" exp-pos)
  126.     (unless (left-char c-label-indent exp-ind)
  127.       (setq exp-ind (pos 0 (pos-line exp-pos))))))
  128.       ;; Next, look at the contents of this line and see if it needs any
  129.       ;; special treatment
  130.       (unless (empty-line-p line-pos)
  131.     (when (regexp-match-line "^[\t\f ]+" line-pos)
  132.       (setq line-pos (match-end)))
  133.     (cond
  134.      ((= (get-char line-pos) ?\{)
  135.       (if (< (pos-col exp-pos) (- c-brace-indent))
  136.           (set-pos-col exp-pos 0)
  137.         (right-char c-brace-indent exp-ind)))
  138.      ((= (get-char line-pos) ?\})
  139.       (left-char c-body-indent exp-ind))
  140.      ((looking-at "case .*:|default[\t ]*:" line-pos)
  141.       (right-char c-case-indent exp-ind))
  142.      ((looking-at "[a-zA-Z_]+[a-zA-Z0-9_]*:" line-pos)
  143.       (right-char c-label-indent exp-ind))))
  144.       (set-pos-line exp-ind (pos-line line-pos))
  145.       exp-ind)))
  146.